/*
 * 「addFlags()」と言う関数を追加しました。
 *	バーコードのスキャン画面を利用する場合、スクリーンをロックされません。
 *	2013/12/23
 *	
 *	dialogを追加しました。バーコードを取得してから、「確認」と「キャンセル」ボタンがポップアップ
 *	「確定」をクリックすると、商品詳細画面に遷移する。
 *	「キャンセル」をクリックすると、ボーコードスキャン画面に戻る。
 *
 *	カメラ開く時点、カメラ関数は異常が有れば、ユーザーインタフェースで「Can't open the camera」
 *	、Logcatと言うログではエラー情報があるはずです。下記の内容が出る場合、
 *	「CameraManager.get().openDriver(surfaceHolder)」のメソッドは異常が有ります。
 *	「open_failed」「initCamera_Exception」
 *	2013/12/25
 * */
package com.komeri.komeriapl;

import static com.komeri.komeriapl.Constants.*;

import java.util.Vector;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;

/**
 * バーコードスキャン画面基底アクティビティ
 * @author Liu Mingjia
 */
public class BaseCaptureActivity extends Activity implements Callback{

	private CaptureActivityHandler handler;

	private ViewfinderView viewfinderView;

	/**surfaceが必要かと判断する***/
	private boolean hasSurface;

	private Vector<BarcodeFormat> decodeFormats;

	private String characterSet;

	private InactivityTimer inactivityTimer;

	private MediaPlayer mediaPlayer;
 
	/**振動スイチ*/
	private boolean vibrate;

	/**戻る*/
	private ImageButton cancelScanButton;

	protected String webname = null;

	/**intentデータ設定キー*/
	public static final String INTENTS_KEY_BARCODE_TYPE = "BARCODE_TYPE";
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Window window = getWindow();
		window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		
		//intentからbarCodeTypeを取得
		Intent intent = getIntent();
		int order = intent.getIntExtra(INTENTS_KEY_BARCODE_TYPE, 0);
		BarCodeType[] values = BarCodeType.values();
		BarCodeType barCodeType = values[order];
		
		try{
			CameraManager.init(getApplication(), barCodeType);
		}catch(Exception e){
			Log.e("CaptureActivity", "onCreate");
		}
		viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
		
		cancelScanButton = (ImageButton) this.findViewById(R.id.btn_cancel_scan);
		
		hasSurface = false;
		
		inactivityTimer = new InactivityTimer(this);
	}
	
	@Override
	public void onResume() {
		
		super.onResume();
		
		SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
		
		SurfaceHolder surfaceHolder = surfaceView.getHolder();
		
		if (hasSurface) {
		
			initCamera(surfaceHolder);
		} else {
		
			surfaceHolder.addCallback(this);
		
			surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		}
		decodeFormats = null;
		
		characterSet = null;
		
		vibrate = true;
		
		cancelScanButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				
				BaseCaptureActivity.this.finish();
			}
		});
	}

	@Override
	public void onPause() {
		super.onPause();
	
		if (handler != null) {
			
			handler.quitSynchronously();
			
			handler = null;
		}
		CameraManager.get().closeDriver();
	}

	@Override
	public void onDestroy() {
		
		inactivityTimer.shutdown();
		
		super.onDestroy();
	}
	
	/**
	 * JANコード情報をホームページに転送する
	 * @param result
	 * @param barcode
	 */
	public void handleDecode(Result result, Bitmap barcode) {
		
		inactivityTimer.onActivity();
	
		playBeepSoundAndVibrate();
		
		if (webname.equals("")) {
			
			Toast.makeText(BaseCaptureActivity.this, getString(R.string.scan_failed), Toast.LENGTH_SHORT)
			        .show();
		}else {
			Goto_Web();
		}
	}
	public void Goto_Web(){
		
		Intent resultIntent = new Intent();
		
		Bundle bundle = new Bundle();
		
		bundle.putString("result", webname);
		
		resultIntent.putExtras(bundle);
		
		this.setResult(RESULT_OK, resultIntent);
		
		BaseCaptureActivity.this.finish();
	}
	/**
	 * カメラ初期化
	 * @param surfaceHolder
	 * */
	private void initCamera(SurfaceHolder surfaceHolder) {
		try {
			CameraManager.get().openDriver(surfaceHolder);
		} catch (Exception ioe) {
			
			Log.e("CaptureActivity", "open_failed");
			Log.e("CaptureActivity", "initCamera_Exception");
			
			Toast.makeText(BaseCaptureActivity.this, getString(R.string.camera_open_failed)
			        , Toast.LENGTH_LONG).show();
			return;
		} 
		if (handler == null) {
			
			handler = new CaptureActivityHandler(this, decodeFormats,characterSet);
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,int height){}

	/**
	 *  SurfaceViewが最初に生成されたときに呼び出される
	 * */
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		
		if (!hasSurface) {
			
			hasSurface = true;
			
			initCamera(holder);
			
			//カメラの初期化が完了し、スキャン枠の矩形が取得できる状態になってからラベルの表示位置を設定する
			//表示位置はスキャン枠の矩形を基準に画面サイズ毎に設定する
			setScanLabelMargin();
		}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		
		hasSurface = false;
	}

	public ViewfinderView getViewfinderView() {
		
		return viewfinderView;
	}

	public Handler getHandler() {
		
		return handler;
	}

	/**
	 * パーシャルリフレッシュ
	 * */
	public void drawViewfinder() {
		
		viewfinderView.drawViewfinder();
	}
	/**
	 * 振動の持続時間
	 * */
	private static final long VIBRATE_DURATION = 200L;

	/**
	 * 振動設定
	 * */
	private void playBeepSoundAndVibrate() {
		
		if (mediaPlayer != null) {
			
			mediaPlayer.start();
		}
		if (vibrate) {
			
			Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
			
			vibrator.vibrate(VIBRATE_DURATION);
		}
	}
	
	/**
	 * ラベルの表示位置設定
	 * */
	private void setScanLabelMargin() {
    	Rect rect = CameraManager.get().getFramingRect();
    	if (rect != null) {
	    	int margin = 0;
	    	int size = CommonUtility.getScreenLayoutSize(this);
	    	
	    	if (size == Configuration.SCREENLAYOUT_SIZE_SMALL) {
	    		margin = (int) getResources().getDimension(R.dimen.scan_label_margin_height_small);
	    	}
	    	else if (size == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
	    		margin = (int) getResources().getDimension(R.dimen.scan_label_margin_height_normal);
	    	}
	    	else if (size == Configuration.SCREENLAYOUT_SIZE_LARGE) {
	    		margin = (int) getResources().getDimension(R.dimen.scan_label_margin_height_large);
	    	}
	    	else if (size == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
	    		margin = (int) getResources().getDimension(R.dimen.scan_label_margin_height_xlarge);
	    	}
	    	
		    TextView label = (TextView)findViewById(R.id.scan_label);
	    	MarginLayoutParams layoutParams = (MarginLayoutParams)label.getLayoutParams();
	    	layoutParams.topMargin = rect.bottom + margin;
	    	label.setLayoutParams(layoutParams);
    	}
	}
}